//package Demo;
import java.util.Random;

/**
 * Takes in an array of solutions and will use one of the selection methods to select breeding
 * partners
 * @author DeMarcus
 *
 */
public class Selection 
{
	public Solution[] solutions;
	public int totalBreeders;
	
	public Selection(Solution[] sols)
	{
		solutions = sols;
		totalBreeders = solutions.length;
	}
	/**
	 * Uses the solution array that was passed in in the constructor and returns an
	 * array of Solutions set up so breeding pairs are right next to each other in the array
	 * @return Solution[]
	 */
	public Solution[] rouleteSelection()
	{
		Solution[] breedpairs = new Solution[totalBreeders];
		Solution[] temp;
		int count = 0;
		while(count < totalBreeders - 1)
		{
			temp = rouletteSelectionHelper();
			if(temp[0] != temp[1])
			{
				breedpairs[count] = temp[0];
				breedpairs[count + 1] = temp[1];
				count += 2;
			}
		}
		return null;
	}
	
	/**
	 * Helper method that pairs up two solutions as breeding partners in the Roulete-Selection
	 */
	private Solution[] rouletteSelectionHelper()
	{
		int totfit = totalFit();
		double totprob = 0;
		double choice;
		double[] fitnessChance = new double[totalBreeders];
		Solution[] breeders = new Solution[2];
		
		boolean picked = false;
		Random rand = new Random();
		
		for(int i = 0; i < totalBreeders; i++)
		{
			fitnessChance[i] = totprob + solutions[i].fitness / totfit;
			totprob += fitnessChance[i];
		}
		
		int j = 0;
		while(j < 1)
		{
			choice = rand.nextDouble();
			for(int i = 0; i < totalBreeders - 1; i++)
			{
				if(choice > fitnessChance[i] && choice < fitnessChance[i + 1])
				{
					breeders[j] = solutions[i];
					picked = true;
					j++;
					break;
				}
			}
			
			if(!picked)
			{
				breeders[j] = solutions[totalBreeders - 1];
			}
			else
				picked = false;
		}
		
		return breeders;
	}
	
	private int totalFit()
	{
		int totfit = 0;
		for(int i = 0; i < totalBreeders; i++)
		{
			totfit += solutions[i].fitness;
		}
		return totfit;
	}
	// randomly selects solutions to bread with 
	public Solution[] tournamentSelection(int subset)
	{
		Random rand = new Random();
		Solution[] subselection;
		Solution[] finalsubsect = new Solution[totalBreeders];
		Solution pick;
		for(int j = 0; j < totalBreeders; j++)
		{
			subselection = randSelector(subset);
			pick = subselection[0];
			for(int i = 1; i < subset; i++)
			{
				if(subselection[i].fitness > pick.fitness)
					pick = subselection[i];
			}
			finalsubsect[j] = pick;
		}
		return finalsubsect;
	}
	
	private Solution[] randSelector(int subset)
	{
		Random rand = new Random();
		Solution temp = null;
		Solution[] subselection = new Solution[subset];
		boolean check = false;
		for(int i = 0; i > subset; i++)
		{
			while(!check)
			{
				check = false;
				temp = solutions[rand.nextInt(totalBreeders)];
				for(Solution s: subselection)
				{
					if (temp == s)
					{
						break;
					}
				}
				check = true;
			}
			subselection[i] = temp;
		}
		return subselection;
	}
	
}